use anyhow::Result;
use serde::{Deserialize, Serialize};
use serialport::{self, SerialPortType};
use std::time::Duration;
use tokio::time::sleep;

use crate::app_mu_stor::OStor;

const BAUDRATE: u32 = 115_200;

#[derive(Serialize, Deserialize, Debug, Clone, Default)]
pub struct Usb {
    name: String,
    product: String,
    manufacturer: String,
}

#[derive(Serialize, Deserialize, Debug, Clone, Default)]
pub struct MUXConfig {
    pub usb: Usb,
}

#[derive(Serialize, Deserialize)]
pub struct Msg {
    msg_type: String,
    msg_text: String,
}

#[tauri::command]
pub async fn rcios_read_cmd(port_name: String, command: String) -> String {
    println!("rcios_connect_cmd:{}", port_name);
    // 这里应该是一个循环在等待命令
    let wait_time = Duration::from_millis(50);
    let port_build = serialport::new(port_name, BAUDRATE);
    if let Ok(mut port) = port_build.timeout(wait_time).open() {
        println!("{:?}",command);
        port.write_all(command.as_bytes()).expect("Failed to write to port");
        sleep(Duration::from_millis(120)).await;

        let mut buf = vec![0; 256]; // 创建一个缓冲区
        let mut bytes_read = 0;
        loop {
            match port.read(&mut buf[bytes_read..]) {
                Ok(0) => break, // 如果没有读取到数据，则退出循环
                Ok(n) => bytes_read += n,
                Err(e) => {
                    eprintln!("Error reading from port: {}", e);
                    break;
                }
            }
            if bytes_read >= buf.len() {
                break; // 如果缓冲区已满，也退出循环
            }
        }
        
        let response = String::from_utf8_lossy(&buf[..bytes_read]);
        println!("Response: {}", response);
        return response.to_string();
        
    }else {
        println!("port build fail");
    }
    

    return "".to_string();
}

#[tauri::command]
pub fn list_usb_cmd() -> Vec<Usb> {
    let mut result: Vec<Usb> = vec![];
    if let Ok(ports) = serialport::available_ports() {
        for p in ports {
            println!("{:?}",p);
            match p.port_type {
                SerialPortType::UsbPort(info) => {
                    let temp = Usb{
                        name: p.port_name.clone(),
                        product: info.product.unwrap_or(p.port_name.clone()),
                        manufacturer: info.manufacturer.unwrap_or_default()
                    };
                    result.push(temp);
                }
                _ => {}
            }
        }
    }
    result
}

#[tauri::command]
pub async fn get_mux_conf_cmd() -> MUXConfig {
    if let Ok(ostor) = OStor::new().await {
        if let Ok(Some(content)) = ostor.get_conf(1, "mux_conf_v1", "default").await {
            if let Ok(conf) = serde_json::from_str::<MUXConfig>(&content) {
                return conf;
            }
        }
    }
    return MUXConfig::default();
}

#[tauri::command]
pub async fn set_mux_conf_cmd(app_conf: MUXConfig) -> String {
    if let (Ok(ostor), Ok(content)) = (OStor::new().await, serde_json::to_string(&app_conf)) {
        if let Ok(()) = ostor.set_conf(1, "mux_conf_v1", "default", content).await {
            return "[set_app_conf_cmd] successful!!!".to_string();
        }
    }
    return "[set_app_conf_cmd] fail...".to_string();
}